using System;
using System.Collections;
using UnityEngine;

public class MessageBubble : MonoBehaviour
{
	public UILabel label;

	public UILabel label2;

	public UILabel label3;

	public UILabel titleLabel;

	public UIWidget mWidget;

	public Transform label2Container;

	public float scaleStart = 1.5f;

	public float scaleEnd = 1f;

	public UISprite bubbleSprite;

	public string bubbleSpriteNameLeft;

	public string bubbleSpriteNameRight;

	protected Transform tracked;

	protected Vector3 worldPos;

	protected Vector3 worldDisplace;

	protected Camera camWorld;

	protected Camera camUI;

	protected Vector3 trDisplace;

	protected Vector3 blDisplace;

	protected float width;

	private bool isAwake;

	private bool initialized;

	private void Awake()
	{
		isAwake = true;
		camWorld = Camera.main;
		camUI = UICamera.mainCamera;
		Vector3[] worldCorners = mWidget.worldCorners;
		width = worldCorners[2].x - worldCorners[1].x;
		trDisplace = (base.transform.position - worldCorners[2]) * 1.1f;
		blDisplace = (base.transform.position - worldCorners[0]) * 1.1f;
		Init();
	}

	private void Init()
	{
		if (!initialized)
		{
			HideSmall();
			Hide();
			initialized = true;
		}
	}

	public void ShowOnSmall(string text, Transform tracked, Vector3 pos)
	{
		Init();
		this.tracked = tracked;
		if (tracked == null)
		{
			worldPos = pos;
		}
		else
		{
			worldDisplace = worldDisplace;
		}
		base.gameObject.SetActive(true);
		label3.cachedGameObject.SetActive(true);
		label3.text = text;
		label3.cachedTransform.localScale = new Vector3(1f, 1.5f, 1f);
		TweenScale.Begin(label3.cachedGameObject, 0.2f, Vector3.one);
		UpdateWorldPos();
	}

	public void HideSmall()
	{
		label3.gameObject.SetActive(false);
	}

	public Coroutine Show(string title, string text, Color textColour, Transform tracked, Vector3 pos, Action callback = null, float hideIn = 120f)
	{
		label.color = textColour;
		Init();
		this.tracked = tracked;
		if (tracked == null)
		{
			worldPos = pos;
		}
		else
		{
			worldDisplace = pos;
		}
		base.gameObject.SetActive(true);
		UITools.ChangeText(titleLabel, title);
		label.text = string.Empty;
		label.cachedGameObject.SetActive(true);
		label2.cachedGameObject.SetActive(false);
		StopAllCoroutines();
		UpdateWorldPos();
		return StartCoroutine(DoShowStatement(text, callback, hideIn));
	}

	public Coroutine Read(string text, Transform tracked, Vector3 pos, Action callback = null, float hideIn = 2f)
	{
		Init();
		this.tracked = tracked;
		if (tracked == null)
		{
			worldPos = pos;
		}
		else
		{
			worldDisplace = pos;
		}
		base.gameObject.SetActive(true);
		label2.text = string.Empty;
		label.cachedGameObject.SetActive(false);
		label2.cachedGameObject.SetActive(true);
		StopAllCoroutines();
		UpdateWorldPos();
		return StartCoroutine(ProcessWholeStatement(text, callback, hideIn));
	}

	public void Hide()
	{
		base.gameObject.SetActive(false);
	}

	private IEnumerator DoShowStatement(string text, Action callback, float hideIn)
	{
		label.text = text;
		label.cachedTransform.localScale = new Vector3(1f, 2f, 1f);
		float duration = 0.25f;
		TweenScale.Begin(label.cachedGameObject, duration, Vector3.one);
		float currentTime2 = 0f;
		while (currentTime2 < duration)
		{
			currentTime2 += RealTime.deltaTime;
			yield return null;
		}
		if (callback != null)
		{
			callback();
		}
		currentTime2 = 0f;
		while (currentTime2 < hideIn)
		{
			currentTime2 += RealTime.deltaTime;
			yield return null;
		}
		Hide();
	}

	private Coroutine RealTimeWaitForSeconds(float seconds)
	{
		return StartCoroutine(DoRealTimeWaitForSeconds(seconds));
	}

	private IEnumerator DoRealTimeWaitForSeconds(float seconds)
	{
		float currentTime = 0f;
		while (currentTime < seconds)
		{
			currentTime += RealTime.deltaTime;
			yield return null;
		}
	}

	private IEnumerator ProcessWholeStatement(string statement, Action callback, float hideIn)
	{
		label2.text = statement;
		float scaleInDuration = 0.2f;
		float alphaStart = 0.5f;
		float alphaEnd = 1f;
		float duration = 0f;
		label2Container.localScale = new Vector3(scaleStart, scaleStart, 1f);
		label2.alpha = alphaStart;
		while (duration < scaleInDuration)
		{
			duration += RealTime.deltaTime;
			float scale = Mathf.Lerp(scaleStart, scaleEnd, duration / scaleInDuration);
			label2Container.localScale = new Vector3(scale, scale, 1f);
			label2.alpha = Mathf.Lerp(alphaStart, alphaEnd, duration / scaleInDuration);
			yield return null;
		}
		label2.alpha = alphaEnd;
		label2Container.localScale = new Vector3(scaleEnd, scaleEnd, 1f);
		yield return RealTimeWaitForSeconds(hideIn);
		Hide();
		if (callback != null)
		{
			Debug.Log("Callback");
			callback();
		}
	}

	private IEnumerator ProcessStatement(string statement, Action callback, float hideIn)
	{
		float durationBetweenLetters = 0f;
		float durationInterpunction = 0f;
		float durationComma = 0f;
		float endDuration = 0f;
		float initialDelay = 0f;
		string speech = string.Empty;
		float currentTime2 = 0f;
		if (initialDelay > 0f)
		{
			yield return RealTimeWaitForSeconds(initialDelay);
		}
		for (int i = 0; i < statement.Length; i++)
		{
			speech += statement[i];
			label2.text = speech;
			currentTime2 = 0f;
			if (durationBetweenLetters > 0f)
			{
				yield return RealTimeWaitForSeconds(durationBetweenLetters);
			}
			char c = statement[i];
			if ((c == '.' || c == '!' || c == '?') && durationInterpunction > 0f)
			{
				yield return RealTimeWaitForSeconds(durationInterpunction);
			}
			if (c == ',' && durationComma > 0f)
			{
				yield return RealTimeWaitForSeconds(durationComma);
			}
		}
		yield return RealTimeWaitForSeconds(endDuration + hideIn);
		Hide();
		if (callback != null)
		{
			Debug.Log("Callback");
			callback();
		}
	}

	private void UpdateWorldPos()
	{
		if (tracked != null)
		{
			worldPos = tracked.position + worldDisplace;
		}
		Vector3 position = camWorld.WorldToScreenPoint(worldPos);
		Transform parent = base.transform.parent;
		Vector3[] localCorners = mWidget.localCorners;
		Vector3 vector = camUI.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0f));
		Vector3 vector2 = blDisplace;
		if (position.x > (float)Screen.width * 0.5f)
		{
			vector2.x = trDisplace.x - width * 0.1f;
			if (bubbleSprite != null)
			{
				bubbleSprite.spriteName = bubbleSpriteNameRight;
			}
		}
		else
		{
			vector2.x += width * 0.1f;
			if (bubbleSprite != null)
			{
				bubbleSprite.spriteName = bubbleSpriteNameLeft;
			}
		}
		Vector3 position2 = camUI.ScreenToWorldPoint(position) + vector2;
		if (position2.y - trDisplace.y > vector.y)
		{
			position2.y += vector.y - position2.y + trDisplace.y;
		}
		Vector3 localPosition = parent.InverseTransformPoint(position2);
		localPosition.z = base.transform.localPosition.z;
		base.transform.localPosition = localPosition;
	}

	private void Update()
	{
		UpdateWorldPos();
	}
}
